home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / ixemlsrc.lha / ixemul / library / kern_sig.c < prev    next >
C/C++ Source or Header  |  1996-01-01  |  26KB  |  1,069 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: kern_sig.c,v 1.6 1994/07/11 00:32:56 rluebbert Exp $
  21.  *
  22.  *  $Log: kern_sig.c,v $
  23.  *  Revision 1.6  1994/07/11  00:32:56  rluebbert
  24.  *  Put issig back in.
  25.  *
  26.  *  Revision 1.5  1994/07/11  00:27:37  rluebbert
  27.  *  Commented out unused issig
  28.  *
  29.  *  Revision 1.4  1994/06/19  15:13:35  rluebbert
  30.  *  *** empty log message ***
  31.  *
  32.  *  Revision 1.2  1992/07/04  19:19:51  mwild
  33.  *  change to new ix_sleep() semantics
  34.  *
  35.  * Revision 1.1  1992/05/14  19:55:40  mwild
  36.  * Initial revision
  37.  *
  38.  *
  39.  *  Since the code originated from Berkeley, the following copyright
  40.  *  header applies as well. The code has been changed, it's not the
  41.  *  original Berkeley code!
  42.  */
  43.  
  44. /*
  45.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  46.  * All rights reserved.
  47.  *
  48.  * Redistribution is only permitted until one year after the first shipment
  49.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  50.  * binary forms are permitted provided that: (1) source distributions retain
  51.  * this entire copyright notice and comment, and (2) distributions including
  52.  * binaries display the following acknowledgement:  This product includes
  53.  * software developed by the University of California, Berkeley and its
  54.  * contributors'' in the documentation or other materials provided with the
  55.  * distribution and in all advertising materials mentioning features or use
  56.  * of this software.  Neither the name of the University nor the names of
  57.  * its contributors may be used to endorse or promote products derived from
  58.  * this software without specific prior written permission.
  59.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  60.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  61.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  62.  *
  63.  *    @(#)kern_sig.c    7.23 (Berkeley) 6/28/90
  64.  */
  65.  
  66. #define KERNEL
  67. #include "ixemul.h"
  68. #include "kprintf.h"
  69.  
  70. #include <stdio.h>
  71. #include <string.h>
  72.  
  73. extern struct ExecBase *SysBase;
  74.  
  75. #include <wait.h>
  76.  
  77. #define    ttystopsigmask    (sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU))
  78. #define    stopsigmask    (sigmask(SIGSTOP)|ttystopsigmask)
  79. #define defaultignmask    (sigmask(SIGCONT)|sigmask(SIGIO)|sigmask(SIGURG)| \
  80.             sigmask(SIGCHLD)|sigmask(SIGWINCH)|sigmask(SIGINFO)|sigmask(SIGMSG))
  81.  
  82. #define getuser(p)    ((struct user *)((p)->pr_Task.tc_TrapData))
  83.  
  84. void setsigvec (int sig, struct sigaction *sa);
  85. void sig_exit (unsigned int code);
  86. void stop (struct user *p);
  87.  
  88.  
  89. /*
  90.  * Can process p send the signal signo to process q?
  91.  */
  92. #define CANSIGNAL(p, q, signo) (1)
  93.  
  94. int
  95. sigaction (int sig, const struct sigaction *nsa, struct sigaction *osa)
  96. {
  97.   struct sigaction vec;
  98.   register struct sigaction *sa;
  99.   int bit;
  100.  
  101.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  102.     {
  103.       errno = EINVAL;
  104.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  105.       return -1;
  106.     }
  107.  
  108.   sa = &vec;
  109.   if (osa)
  110.     {
  111.       sa->sa_handler = u.u_signal[sig];
  112.       sa->sa_mask = u.u_sigmask[sig];
  113.       bit = sigmask(sig);
  114.       sa->sa_flags = 0;
  115.       if ((u.u_sigonstack & bit) != 0)
  116.     sa->sa_flags |= SA_ONSTACK;
  117.  
  118.       if ((u.u_sigintr & bit) == 0)
  119.     sa->sa_flags |= SA_RESTART;
  120.  
  121.       if (u.p_flag & SNOCLDSTOP)
  122.     sa->sa_flags |= SA_NOCLDSTOP;
  123.  
  124.       *osa = *sa;
  125.     }
  126.  
  127.   if (nsa)
  128.     {
  129.       *sa = *nsa;
  130.       setsigvec(sig, sa);
  131.     }
  132.   
  133.   return (0);
  134. }
  135.  
  136. void
  137. setsigvec (int sig, struct sigaction *sa)
  138. {
  139.   register int bit;
  140.  
  141.   bit = sigmask(sig);
  142.   /*
  143.    * Change setting atomically.
  144.    */
  145.   Disable();
  146.  
  147.   u.u_signal[sig] = sa->sa_handler;
  148.   u.u_sigmask[sig] = sa->sa_mask &~ sigcantmask;
  149.  
  150.   if ((sa->sa_flags & SA_RESTART) == 0)
  151.     u.u_sigintr |= bit;
  152.   else
  153.     u.u_sigintr &= ~bit;
  154.  
  155.   if (sa->sa_flags & SA_ONSTACK)
  156.     u.u_sigonstack |= bit;
  157.   else
  158.     u.u_sigonstack &= ~bit;
  159.  
  160.   if (sig == SIGCHLD) 
  161.     {
  162.       if (sa->sa_flags & SA_NOCLDSTOP)
  163.     u.p_flag |= SNOCLDSTOP;
  164.       else
  165.     u.p_flag &= ~SNOCLDSTOP;
  166.     }
  167.  
  168.   /*
  169.    * Set bit in p_sigignore for signals that are set to SIG_IGN,
  170.    * and for signals set to SIG_DFL where the default is to ignore.
  171.    * However, don't put SIGCONT in p_sigignore,
  172.    * as we have to restart the process.
  173.    */
  174.   if (sa->sa_handler == SIG_IGN ||
  175.       (bit & defaultignmask && sa->sa_handler == SIG_DFL)) 
  176.     {
  177.       u.p_sig &= ~bit;        /* never to be seen again */
  178.       if (sig != SIGCONT)
  179.     u.p_sigignore |= bit;    /* easier in _psignal */
  180.       u.p_sigcatch &= ~bit;
  181.     }
  182.   else 
  183.     {
  184.       u.p_sigignore &= ~bit;
  185.       if (sa->sa_handler == SIG_DFL)
  186.     u.p_sigcatch &= ~bit;
  187.       else
  188.     u.p_sigcatch |= bit;
  189.     }
  190.  
  191.   Enable();
  192. }
  193.  
  194.  
  195. /*
  196.  * Manipulate signal mask.
  197.  */
  198.  
  199. int
  200. sigprocmask (int how, const sigset_t *mask, sigset_t *omask)
  201. {
  202.   if (omask)
  203.     *omask = u.p_sigmask;
  204.  
  205.   if (mask)
  206.     {
  207.       Disable();
  208.  
  209.       switch (how) 
  210.         {
  211.         case SIG_BLOCK:
  212.       u.p_sigmask |= *mask &~ sigcantmask;
  213.       break;
  214.  
  215.         case SIG_UNBLOCK:
  216.       u.p_sigmask &= ~*mask;
  217.       break;
  218.  
  219.         case SIG_SETMASK:
  220.       u.p_sigmask = *mask &~ sigcantmask;
  221.       break;
  222.     
  223.         default:
  224.       errno = EINVAL;
  225.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  226.       goto err_ret;
  227.         }
  228.  
  229.       Enable();
  230.     }
  231.  
  232.   if (CURSIG (&u))
  233.     setrun (FindTask (0));
  234.  
  235.   return 0;
  236.  
  237. err_ret:
  238.   Enable ();
  239.   return -1;
  240. }
  241.  
  242. int
  243. sigpending (sigset_t *sigs)
  244. {
  245.   *sigs = u.p_sig;
  246.   return 0;
  247. }
  248.  
  249. /*
  250.  * Generalized interface signal handler, 4.3-compatible.
  251.  * (included in amiga version, because I want to reduce the static part of the
  252.  *  library to a minimum)
  253.  */
  254. /* ARGSUSED */
  255. int
  256. sigvec(int sig, const struct sigvec *nsv, struct sigvec *osv)
  257. {
  258.   struct sigvec vec;
  259.   register struct sigvec *sv;
  260.   struct user *p = &u;
  261.   int bit;
  262.  
  263.   if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
  264.     {
  265.       *p->u_errno = EINVAL;
  266.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  267.       return -1;
  268.     }
  269.  
  270.   sv = &vec;
  271.   if (osv) 
  272.     {
  273.       *(sig_t *)&sv->sv_handler = p->u_signal[sig];
  274.       sv->sv_mask = p->u_sigmask[sig];
  275.       bit = sigmask(sig);
  276.       sv->sv_flags = 0;
  277.       if ((p->u_sigonstack & bit) != 0)
  278.     sv->sv_flags |= SV_ONSTACK;
  279.       if ((p->u_sigintr & bit) != 0)
  280.     sv->sv_flags |= SV_INTERRUPT;
  281.       if (p->p_flag & SNOCLDSTOP)
  282.     sv->sv_flags |= SA_NOCLDSTOP;
  283.       *osv = *sv;
  284.     }
  285.  
  286.   if (nsv) 
  287.     {
  288.       *sv = *nsv;
  289.       sv->sv_flags ^= SA_RESTART;    /* opposite of SV_INTERRUPT */
  290.       setsigvec(sig, (struct sigaction *)sv);
  291.     }
  292.  
  293.   return (0);
  294. }
  295.  
  296. sigset_t
  297. sigblock (sigset_t mask)
  298. {
  299.   sigset_t result;
  300.  
  301.   Disable();
  302.   result = u.p_sigmask;
  303.   u.p_sigmask |= mask &~ sigcantmask;
  304.   (void) Enable();
  305.  
  306.   errno = 0;
  307.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  308.   return result;
  309. }
  310.  
  311. sigset_t
  312. sigsetmask(sigset_t mask)
  313. {
  314.   sigset_t result;
  315.   struct user *p = &u;
  316.  
  317.   Disable();
  318.   result = u.p_sigmask;
  319.   u.p_sigmask = mask &~ sigcantmask;
  320.   Enable();
  321.  
  322.   if (CURSIG (p))
  323.     setrun (FindTask (0));
  324.  
  325.   errno = 0;
  326.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  327.   return result;
  328. }
  329.  
  330. /*
  331.  * Suspend process until signal, providing mask to be set
  332.  * in the meantime. 
  333.  */
  334. /* ARGSUSED */
  335. int
  336. sigsuspend (const sigset_t *mask)
  337. {
  338.   struct user *p = &u;
  339.  
  340.   /*
  341.    * When returning from sigpause, we want
  342.    * the old mask to be restored after the
  343.    * signal handler has finished.  Thus, we
  344.    * save it here and mark the proc structure
  345.    * to indicate this (should be in u.).
  346.    */
  347.  
  348.   Disable ();
  349.   p->u_oldmask = p->p_sigmask;
  350.   p->p_flag |= SOMASK;
  351.   p->p_sigmask = *mask &~ sigcantmask;
  352.  
  353.  
  354.   /* NOTE: we have to specify SIGBREAKF_CTRL_C here, as the OS doesn't seem
  355.    *       to reschedule our task, if it receives a signal it isn't waiting
  356.    *       for. If SIGINT is ignored, then this will jump back into the Wait,
  357.    *       if not, we're leaving correctly, since we waited for a signal
  358.    *       that now occured (lucky we, the OS tests the Recvd-field before
  359.    *       tc_Launch has a chance to reset it ;-))
  360.    */
  361.  
  362.   while (ix_sleep ((caddr_t)p, "sigsuspend") == 0);
  363.   Enable ();
  364.  
  365.   setrun (FindTask (0));
  366.  
  367.   p->p_sigmask = p->u_oldmask;
  368.  
  369.   if (CURSIG (p))
  370.     setrun (FindTask (0));
  371.  
  372.   /* always return EINTR rather than ERESTART... */
  373.   errno = EINTR;
  374.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  375.   return -1;
  376. }
  377.  
  378.  
  379. int
  380. sigpause (sigset_t mask)
  381. {
  382.   return sigsuspend (&mask);
  383. }
  384.  
  385.  
  386. /* ARGSUSED */
  387. int
  388. sigstack(const struct sigstack *nss, struct sigstack *oss)
  389. {
  390.   if (oss) *oss = u.u_sigstack;
  391.   if (nss) u.u_sigstack = *nss;
  392.  
  393.   return 0;
  394. }
  395.  
  396.  
  397. /*
  398.  * Initialize signal state for process 0;
  399.  * set to ignore signals that are ignored by default.
  400.  */
  401. void
  402. siginit(struct user *p)
  403. {
  404.   p->p_sigignore = defaultignmask &~ sigmask(SIGCONT);
  405. }
  406.  
  407. /*
  408.  * This looks for the process p, validates it, and checks, whether the process
  409.  * is currently using our signal mechanism (checks magic cookie in struct user)
  410.  */
  411. static inline struct Task *
  412. pfind (pid_t p)
  413. {
  414.   struct Task *t;
  415.   
  416.   if (p && !(p & 1))
  417.     {
  418.       t = (struct Task *) p;
  419.       if (t->tc_Node.ln_Type == NT_TASK ||
  420.           t->tc_Node.ln_Type == NT_PROCESS)
  421.         {
  422.           struct user *tu = (struct user *) t->tc_TrapData;
  423.           if (tu && !((int)t->tc_TrapData & 1) && tu->u_ixbase == u.u_ixbase)
  424.         return t;
  425.     }
  426.     }
  427.   else if (! p)
  428.     return FindTask (0);
  429.  
  430.   return 0;
  431. }
  432.  
  433. /* ARGSUSED */
  434. int
  435. kill(pid_t pid, int signo)
  436. {
  437.   register struct Task *t;
  438.  
  439.   if ((unsigned) signo >= NSIG)
  440.     {
  441.       errno = EINVAL;
  442.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  443.       return -1;
  444.     }
  445.  
  446.   if (pid >= 0)
  447.     {
  448.       /* kill single process */
  449.       t = pfind(pid);
  450.       if (t == 0)
  451.         {
  452.       /* there is a small chance, if pid == 0, that we may send the signal
  453.        * as well. If signo == SIGINT, and pid refers to a valid Task, we send
  454.        * it a SIGBREAKF_CTRL_C */
  455.       if ((signo == SIGINT) && pid && !(pid & 1))
  456.         {
  457.           t = (struct Task *) pid;
  458.           if (t->tc_Node.ln_Type == NT_TASK ||
  459.               t->tc_Node.ln_Type == NT_PROCESS)
  460.             {
  461.           Signal (t, SIGBREAKF_CTRL_C);
  462.           return 0;
  463.         }
  464.         }
  465.  
  466.           errno = ESRCH;
  467.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  468.           return -1;
  469.         }
  470.     
  471.       if (signo)
  472.     _psignal(t, signo);
  473.     
  474.       return (0);
  475.     }
  476.  
  477.   /* signalling process groups is not (yet) implemented */  
  478.   errno = ESRCH;
  479.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  480.   return -1;
  481. }
  482.  
  483. /* ARGSUSED */
  484. int
  485. killpg(int pgid, int signo)
  486. {
  487.   if ((unsigned) signo >= NSIG)
  488.     errno = EINVAL;
  489.   else
  490.     errno = ESRCH;
  491.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  492.  
  493.   /* signalling process groups is not (yet) implemented */  
  494.   return -1;
  495. }
  496.  
  497. /*
  498.  * Send a signal caused by a trap to the current process.
  499.  * If it will be caught immediately, deliver it with correct code.
  500.  * Otherwise, post it normally.
  501.  */
  502. void trapsignal(struct Task *t, int sig, unsigned code, void *addr)
  503. {
  504.   int mask;
  505.  
  506.   mask = sigmask(sig);
  507.   if ((u.p_flag & STRC) == 0 && (u.p_sigcatch & mask) != 0 &&
  508.       (u.p_sigmask & mask) == 0)
  509.     {
  510.       u.u_ru.ru_nsignals++;
  511.       sendsig(t->tc_TrapData, u.u_signal[sig], sig, u.p_sigmask, code, addr);
  512.       u.p_sigmask |= u.u_sigmask[sig] | mask;
  513.       setrun (t);
  514.     }
  515.   else
  516.     {
  517.       u.u_code = code;    /* XXX for core dump/debugger */
  518.       _psignal(t, sig);
  519.     }
  520. }
  521.  
  522. /*
  523.  * Create a core image on the file "core".
  524.  * It writes UPAGES block of the
  525.  * user.h area followed by the entire
  526.  * data+stack segments.
  527.  */
  528. int core(void)
  529. {
  530.   return -1;
  531. }
  532.  
  533. /*
  534.  * Send the specified signal to the specified process.
  535.  * Most signals do not do anything directly to a process;
  536.  * they set a flag that asks the process to do something to itself.
  537.  * Exceptions:
  538.  *   o When a stop signal is sent to a sleeping process that takes the default
  539.  *     action, the process is stopped without awakening it.
  540.  *   o SIGCONT restarts stopped processes (or puts them back to sleep)
  541.  *     regardless of the signal action (eg, blocked or ignored).
  542.  * Other ignored signals are discarded immediately.
  543.  */
  544. void
  545. _psignal(struct Task *t, int sig)    /* MAY be called in Supervisor/Interrupt  !*/
  546. {
  547.   register sig_t action;
  548.   /* may be another process, so don't use u. here ! */
  549.   struct user *p = (struct user *)t->tc_TrapData;
  550.   int mask;
  551.  
  552.  
  553.   mask = sigmask(sig);
  554.  
  555.   /*
  556.    * If proc is traced, always give parent a chance.
  557.    */
  558.   if (p->p_flag & STRC)
  559.     action = SIG_DFL;
  560.   else 
  561.     {
  562.  
  563.       /* NOTE AMIGA !
  564.        * I can't allow for trap signals to be either ignored or masked out.
  565.        * This would cause the trap to reoccur immediately again, resulting
  566.        * in a deadly loop. So if such a signal gets here, it is converted
  567.        * in a SIGILL, masked in, not ignored, not caught, that's it.
  568.        */
  569.       if (((mask & p->p_sigignore) || (mask & p->p_sigmask))
  570.       && (sig == SIGILL  || sig == SIGBUS || sig == SIGFPE || 
  571.           sig == SIGTRAP || sig == SIGEMT))
  572.     {
  573.       sig = SIGILL;
  574.       mask = sigmask (sig);
  575.       p->p_sigignore &= ~mask;
  576.       p->p_sigmask   &= ~mask;
  577.       p->p_sigcatch  &= ~mask;
  578.       /* that's it, SIGILL is now reset to SIG_DFL, which will exit() */
  579.     }
  580.  
  581.       /*
  582.        * If the signal is being ignored,
  583.        * then we forget about it immediately.
  584.        * (Note: we don't set SIGCONT in p_sigignore,
  585.        * and if it is set to SIG_IGN,
  586.        * action will be SIG_DFL here.)
  587.        */
  588.      if (p->p_sigignore & mask)
  589.     return;
  590.  
  591.      if (p->p_sigmask & mask)
  592.     action = SIG_HOLD;
  593.      else if (p->p_sigcatch & mask)
  594.     action = SIG_CATCH;
  595.      else
  596.     action = SIG_DFL;
  597.     }
  598.  
  599.   switch (sig) 
  600.     {
  601.     case SIGTERM:
  602.       if ((p->p_flag&STRC) || action != SIG_DFL)
  603.     break;
  604.     /* FALLTHROUGH */
  605.  
  606.     case SIGKILL:
  607.       break;
  608.  
  609.     case SIGCONT:
  610.       p->p_sig &= ~stopsigmask;
  611.       break;
  612.  
  613.     case SIGTSTP:
  614.     case SIGTTIN:
  615.     case SIGTTOU:
  616.     case SIGSTOP:
  617.       p->p_sig &= ~sigmask(SIGCONT);
  618.       break;
  619.     }
  620.   p->p_sig |= mask;
  621.  
  622.   /*
  623.    * Defer further processing for signals which are held,
  624.    * except that stopped processes must be continued by SIGCONT.
  625.    */
  626.   if (action == SIG_HOLD && (sig != SIGCONT || p->p_stat != SSTOP))
  627.     return;
  628.  
  629.   setrun(t);
  630. }
  631.  
  632. /* An ugly way to pass arguments to stopped_process_handler, but OK as
  633.    we're in Forbid() until the args are copied.  */
  634. static int ugly_mask;
  635.  
  636. int doing_sigtrap = 0;
  637.  
  638. struct trace_ignore
  639.   {
  640.     int signal;
  641.     pid_t pid;
  642.     struct trace_ignore *next;
  643.   };
  644.  
  645. /* A linked list of signals we don't stop
  646.    (ie., that we don't tell the debugger about) on.  */
  647. /* fixme: use this, nuke SIGNSTRC!  */
  648. /*static struct trace_ignore *ignore_list;*/
  649.  
  650. void
  651. stopped_process_handler (struct reg *regs)
  652. {
  653.   /* We are running in user mode in the context of the exec Task that is
  654.      (in the view of other ixemul.library processes) a stopped process.
  655.      We got here from the stop_process_glue routine.  */
  656.  
  657.   /* Put up a message port for another process to comunicate with us,
  658.      communication happens through ptrace() or setrun().  */
  659.  
  660.   extern caddr_t stop_rte_pc;
  661.   struct Task *task = FindTask(0);
  662.   struct user *p = task->tc_TrapData;
  663.   struct MsgPort message_port, *port = &message_port;
  664.   int mask = ugly_mask;
  665.   int sig;
  666.  
  667.   /* Allocate unique name space on stack to allow several stopped processes.  */
  668.   char portname[17] = "ix.SSTOP12345678";
  669.  
  670.   /* Give parent's ptrace() a way to find our register set.  */
  671.   p->u_regs = regs;
  672.  
  673.   /* Put hex address of our struct user in the port name.  */
  674.   sprintf (&portname[8], "%08x", (unsigned)p);
  675.   KPRINTF(("**** SSTOP stopped_process_handler(): portname=`%s'\n", portname));
  676.  
  677.   message_port.mp_Node.ln_Name = portname;
  678.   message_port.mp_Node.ln_Pri = 0;
  679.   message_port.mp_Node.ln_Type = NT_MSGPORT;
  680.  
  681.   message_port.mp_Flags = PA_SIGNAL;
  682.   message_port.mp_SigBit = p->p_zombie_sig;  /* An otherwise unused signal.  */
  683.   message_port.mp_SigTask = task;
  684.   AddPort (port);
  685.  
  686.   KPRINTF(("SSTOP: stop_rte_pc=0x%lx\n", stop_rte_pc));
  687.   if (doing_sigtrap)
  688.     {
  689.       KPRINTF(("SSTOP: doing SIGTRAP, incrementing PC over trap\n"));
  690.       stop_rte_pc += 2;
  691.       doing_sigtrap = 0;
  692.     }
  693.  
  694.   while (p->p_stat != SRUN)
  695.     {
  696.       unsigned int deb;
  697.  
  698.       KPRINTF(("SSTOP: Wait (1<<p->p_zombie_sig);\n"));
  699.       Wait (1<<p->p_zombie_sig);
  700.       deb = p->p_stat;
  701.       KPRINTF(("SSTOP: Wait (1<<p->p_zombie_sig); done, p->p_stat=%lx\n", deb));
  702.     }
  703.  
  704.  
  705.   /* If parent wants us to take the signal, then it will leave it in p->p_xstat;
  706.      otherwise we just look for signals again.  */
  707.   p->p_sig &= ~mask;  /* clear the old signal */
  708.  
  709. /* fixme: temporary until I've figured out how to deliver signals to a
  710.    stopped process....  Just clear a possible signal from the parent. */
  711.   p->p_xstat = 0;
  712.  
  713.   sig = p->p_xstat;
  714.   if (sig == 0)
  715.     goto leave;
  716.  
  717.   p->p_flag |= SIGNSTRC;  /* Don't let debugger know about this signal.  */
  718.   _psignal (task, sig);
  719.  
  720.  leave:  
  721.  
  722.   /* Time to resume the task.  */
  723.   RemPort (port);
  724.  
  725.   /* The matching Forbid() is in issig(), just before we drop into this
  726.      routine in usermode.  */
  727.   Permit ();
  728.  
  729.   /* This is handled by the glue routine, so we just return to it.  */
  730.   return;
  731. }
  732.  
  733. /*
  734.  * If the current process has a signal to process (should be caught
  735.  * or cause termination, should interrupt current syscall),
  736.  * return the signal number.  Stop signals with default action
  737.  * are processed immediately, then cleared; they aren't returned.
  738.  * This is asked at least once each time a process enters the
  739.  * system (though this can usually be done without actually
  740.  * calling issig by checking the pending signal masks.)
  741.  */
  742. int
  743. issig(struct user *p)    /* called in SUPERVISOR */
  744. {
  745.   register int sig, mask;
  746.   u_int sr;
  747.  
  748.   KPRINTF(("issig(task=%lx)\n", SysBase->ThisTask));
  749.  
  750.   asm volatile (" 
  751.     movel a5,a0
  752.     lea      Lget_sr,a5
  753.     movel 4:w,a6
  754.     jsr      a6@(-0x1e)
  755.     movel a1,%0
  756.     bra      Lskip
  757. Lget_sr:
  758.     movew sp@,a1    | get sr register from the calling function
  759.     rte
  760. Lskip:
  761.     movel a0,a5
  762.     " : "=g" (sr) : : "a0", "a1", "a6");
  763.  
  764.   for (;;)
  765.     {
  766.       mask = p->p_sig &~ p->p_sigmask;
  767.       if (p->p_flag&SVFORK)
  768.     mask &= ~stopsigmask;
  769.  
  770.       if (mask == 0)         /* no signal to send */
  771.     return 0;
  772.  
  773.       sig = ffs((long)mask);
  774.       mask = sigmask(sig);
  775.       /*
  776.        * We should see pending but ignored signals
  777.        * only if STRC was on when they were posted.
  778.        */
  779.       if ((mask & p->p_sigignore) && (p->p_flag & STRC) == 0) 
  780.         {
  781.           p->p_sig &= ~mask;
  782.       continue;
  783.     }
  784.  
  785.       if ((p->p_flag & STRC) && (sr & 0x2000) == 0)
  786.         KPRINTF(("issig(task=%lx): ### NOT IN SUPERVISOR\n", SysBase->ThisTask));
  787.  
  788.       if ((p->p_flag & STRC)
  789.       && (p->p_flag & SIGNSTRC) == 0
  790.       && (p->p_flag & SVFORK) == 0) 
  791.         {
  792.       extern void *stop_process;
  793.  
  794.       /*
  795.        * If traced, always stop, and stay
  796.        * stopped until released by the parent.
  797.        */
  798.       if (doing_sigtrap)
  799.         {
  800.           KPRINTF(("issig(task=%lx): ...stopping... SIGTRAP\n", SysBase->ThisTask));
  801.           p->p_xstat = SIGTRAP;
  802.         }
  803.       else
  804.         {
  805.           KPRINTF(("issig(task=%lx): ...stopping... Setting p->p_xstat = %ld\n", SysBase->ThisTask, sig));
  806.           p->p_xstat = sig;
  807.         }
  808.       KPRINTF(("issig(task=%lx): ...stopping... Sending SIGCHLD to parent %lx\n", SysBase->ThisTask, p->p_pptr));
  809.       _psignal((struct Task *)p->p_pptr, SIGCHLD);
  810.       stop (p);
  811.       Forbid ();
  812.  
  813.       if (sr & 0x2000)
  814.         {
  815.           KPRINTF(("issig(task=%lx): ...stopping... while in supervisor\n", SysBase->ThisTask));
  816.           stop_process = stopped_process_handler;
  817.           return 0;  /* Drop into the context of the task.  */
  818.         }
  819.       else
  820.         {
  821.           struct reg regs;
  822.  
  823.           memset(®s, 0, sizeof(struct reg));
  824.           KPRINTF(("issig(task=%lx): ...stopping... while NOT in supervisor\n", SysBase->ThisTask));
  825.           stopped_process_handler (®s);
  826.           return 0;
  827.         }
  828.  
  829. #if 0
  830.       do 
  831.             {
  832.           stop ();
  833.           /* swtch (); */
  834.         } 
  835.           while (/* !procxmt(p) &&
  836.             NetBSD-1.0 doesn't care about this.  --vinsci */
  837.          p->p_flag & STRC);
  838. #endif
  839. #if 0
  840. /* Mmmm, control flow never gets here. Have to check this out */
  841.       /*
  842.        * If the traced bit got turned off,
  843.        * go back up to the top to rescan signals.
  844.        * This ensures that p_sig* and u_signal are consistent.
  845.        */
  846.       if ((p->p_flag & STRC) == 0)
  847.         continue;
  848.  
  849.       /*
  850.        * If parent wants us to take the signal,
  851.        * then it will leave it in p->p_xstat;
  852.        * otherwise we just look for signals again.
  853.        */
  854.       p->p_sig &= ~mask;    /* clear the old signal */
  855.       sig = p->p_xstat;
  856.       if (sig == 0)
  857.         continue;
  858.  
  859.       /*
  860.        * Put the new signal into p_sig.
  861.        * If signal is being masked,
  862.        * look for other signals.
  863.        */
  864.       mask = sigmask(sig);
  865.       p->p_sig |= mask;
  866.       if (p->p_sigmask & mask)
  867.         continue;
  868. #endif
  869.     }
  870.  
  871.       /*
  872.        * Decide whether the signal should be returned.
  873.        * Return the signal's number, or fall through
  874.        * to clear it from the pending mask.
  875.        */
  876.       switch ((int)p->u_signal[sig]) 
  877.         {
  878.     case SIG_DFL:
  879. #if notyet
  880.       /*
  881.        * Don't take default actions on system processes.
  882.        */
  883.       if (p->p_ppid == 0)
  884.         break;        /* == ignore */
  885. #endif
  886.       /*
  887.        * If there is a pending stop signal to process
  888.        * with default action, stop here,
  889.        * then clear the signal.  However,
  890.        * if process is member of an orphaned
  891.        * process group, ignore tty stop signals.
  892.        */
  893.       if (mask & stopsigmask) 
  894.         {
  895. #if notyet
  896.           if (p->p_flag&STRC ||
  897.           (p->p_pgru.pg_jobc == 0 && mask & ttystopsigmask))
  898.         break;    /* == ignore */
  899.           u.p_xstat = sig;
  900.           stop(p);
  901.           if ((u.p_pptr->p_flag & SNOCLDSTOP) == 0)
  902.         _psignal(u.p_pptr, SIGCHLD);
  903.           swtch();
  904. #endif
  905.           break;
  906.         } 
  907.           else if (mask & defaultignmask)
  908.         {
  909.           /*
  910.            * Except for SIGCONT, shouldn't get here.
  911.            * Default action is to ignore; drop it.
  912.            */
  913.           break;        /* == ignore */
  914.         }
  915.       else
  916.         return (sig);
  917.       /*NOTREACHED*/
  918.  
  919.     case SIG_IGN:
  920.       /*
  921.        * Masking above should prevent us ever trying
  922.        * to take action on an ignored signal other
  923.        * than SIGCONT, unless process is traced.
  924.        */
  925. #if 0
  926.       if (sig != SIGCONT && (u.p_flag&STRC) == 0)
  927.         printf("issig\n");
  928. #endif
  929.       break;        /* == ignore */
  930.  
  931.     default:
  932.       /*
  933.        * This signal has an action, let
  934.        * psig process it.
  935.        */
  936.       return (sig);
  937.     }
  938.       u.p_sig &= ~mask;        /* take the signal! */
  939.     }
  940.   /* NOTREACHED */
  941. }
  942.  
  943. /*
  944.  * Put the argument process into the stopped
  945.  * state and notify the parent via wakeup.
  946.  * Signals are handled elsewhere.
  947.  * The process must not be on the run queue.
  948.  */
  949. void stop(struct user *p)
  950. {
  951.   p->p_stat = SSTOP;
  952.   p->p_flag &= ~SWTED;
  953.   KPRINTF(("stop(): waking up parent on wchan=%lx\n",
  954.       p->p_pptr->pr_Task.tc_TrapData));
  955.   ix_wakeup((u_int) p->p_pptr->pr_Task.tc_TrapData);
  956. }
  957.  
  958. /*
  959.  * Perform the action specified by the current signal.
  960.  * The usual sequence is:
  961.  *    if (sig = CURSIG(p))
  962.  *        psig(p, sig);
  963.  */
  964. void
  965. psig(struct user *p, int sig)    /* called in SUPERVISOR */
  966. {
  967.   int code, mask, returnmask;
  968.   register sig_t action; 
  969.  
  970.   do 
  971.     {
  972.       mask = sigmask(sig);
  973.       p->p_sig &= ~mask;
  974.       action = p->u_signal[sig];
  975.       if (action != SIG_DFL) 
  976.         {
  977.        /*
  978.         * Set the new mask value and also defer further
  979.         * occurences of this signal.
  980.         *
  981.         * Special case: user has done a sigpause.  Here the
  982.         * current mask is not of interest, but rather the
  983.          * mask from before the sigpause is what we want
  984.         * restored after the signal processing is completed.
  985.         */
  986. #if usermode
  987.       /* not needed here, no interrupt will play with the signalmask... */
  988.       (void) Disable();
  989. #endif
  990.       if (p->p_flag & SOMASK)
  991.         {
  992.           returnmask = p->u_oldmask;
  993.           p->p_flag &= ~SOMASK;
  994.         }
  995.       else
  996.         returnmask = p->p_sigmask;
  997.       p->p_sigmask |= p->u_sigmask[sig] | mask;
  998. #if usermode
  999.       (void) Enable();
  1000. #endif
  1001.  
  1002.       p->u_ru.ru_nsignals++;
  1003.       if (p->u_sig != sig)
  1004.         {
  1005.           KPRINTF(("psig(): code = 0;"));
  1006.           code = 0;
  1007.         }
  1008.       else
  1009.         {
  1010.           KPRINTF(("psig(): code = u.u_code;\n"));
  1011.           code = p->u_code;
  1012.           p->u_code = 0;
  1013.         }
  1014.       KPRINTF(("kern_sig.c:psig(): doing sendsig(p, action, sig, returnmask, code, 0);\n"));
  1015.       sendsig(p, action, sig, returnmask, code, 0);
  1016.       continue;
  1017.     }
  1018.  
  1019. #if whatdoesthisdo
  1020.       p->u_acflag |= AXSIG;
  1021. #endif
  1022.  
  1023.       switch (sig) 
  1024.         {
  1025.     case SIGILL:
  1026.     case SIGIOT:
  1027.     case SIGBUS:
  1028.     case SIGQUIT:
  1029.     case SIGTRAP:
  1030.     case SIGEMT:
  1031.     case SIGFPE:
  1032.     case SIGSEGV:
  1033.     case SIGSYS:
  1034.       p->u_sig = sig;
  1035.       if (core() == 0)
  1036.         sig |= WCOREFLAG;
  1037.     }
  1038.       /* we can't call exit() when in supervisor mode, have to do this just like
  1039.        * it was a signal passed on its own frame */
  1040.       sendsig(p, sig_exit, sig, 0, 0, 0);
  1041.       /* NOTREACHED */
  1042.     
  1043.   } while ((sig = CURSIG(p)));
  1044. }
  1045.  
  1046. static void sigprocessgrp(struct Process *proc, int pgrp, int signal)
  1047. {
  1048.   struct Process *p;
  1049.  
  1050.   for (p = getuser(proc)->p_cptr; p; p = getuser(p)->p_osptr)
  1051.     sigprocessgrp(p, pgrp, signal);
  1052.   if (getuser(proc)->p_pgrp == pgrp)
  1053.     _psignal((struct Task *)proc, signal);
  1054. }
  1055.  
  1056. void _psignalgrp(struct Process *proc, int signal)
  1057. {
  1058.   struct Process *p = getuser(proc)->p_pptr;
  1059.   struct Process *ok = proc;
  1060.  
  1061.   /* traverse to the top of the process-tree */
  1062.   while (p && p != (struct Process *)1)
  1063.     {
  1064.       ok = p;
  1065.       p = getuser(p)->p_pptr;
  1066.     }
  1067.   sigprocessgrp(ok, getuser(proc)->p_pgrp, signal);
  1068. }
  1069.